package fr.ul.ade.maquette.ui;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

import fr.ul.ade.maquette.R;
import fr.ul.ade.maquette.ui.ScheduleListFragment.OnScheduleActionListener;
import fr.ul.ade.maquette.ui.mobile.CreateSchedule;
import fr.ul.ade.maquette.ui.mobile.ScheduleDetails;
import fr.ul.ade.maquette.ui.util.Bundles;

/**
 * Activité principale pour la version tablette et activité affichant la liste
 * des cours pour la version mobile.
 * 
 * @author Michaël Schnell
 * @since Jun 10, 2013
 * 
 * @version 1.0
 */
public class ScheduleList
		extends SherlockFragmentActivity
		implements OnScheduleActionListener {

	/** Etat des fragments pour la version tablette */
	Bundle state;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.schedule_list);
		this.getSupportActionBar()
				.setTitle(R.string.schedule_list_activity_title);
		this.getSupportActionBar().setIcon(R.drawable.icon);

		// On est sur une tablette
		if (this.findViewById(R.id.left_fragment_container) != null) {
			if (savedInstanceState == null) {
				this.state = new Bundle();
				this.state.putInt(Bundles.FRAGMENT_STATE,
						ScheduleListState.OTHER);

				FragmentTransaction transaction = this
						.getSupportFragmentManager().beginTransaction();
				addFragments(savedInstanceState, transaction);
				transaction.commit();
			} else {
				this.state = savedInstanceState
						.getBundle(Bundles.ACTIVITY_STATE);
			}
		}

	}

	/**
	 * Remplit les fragments du milieu (mode paysage) et de droite en utilisant
	 * les informations stockés dans savedInstanceState.
	 * 
	 * @param savedInstanceState
	 * @param transaction
	 */
	private void addFragments(Bundle savedInstanceState,
			FragmentTransaction transaction) {
		Fragment fragment;
		switch (this.state.getInt(Bundles.FRAGMENT_STATE)) {
		case ScheduleListState.OTHER:
			fragment = ScheduleListFragment.newInstance();
			transaction.add(R.id.left_fragment_container, fragment);
			transaction.show(fragment);
			fragment = EmptyFragment.newInstance();
			transaction.add(R.id.middle_fragment_container,
					fragment,
					"middle_fragment");
			transaction.show(fragment);
			break;

		case ScheduleListState.DETAILS:
			fragment = ScheduleListFragment.newInstance();
			transaction.add(R.id.left_fragment_container, fragment);
			transaction.show(fragment);
			fragment = ScheduleDetailsFragment.newInstance(savedInstanceState
					.getLong(Bundles.SCHEDULE_ID));
			transaction.add(R.id.middle_fragment_container,
					fragment,
					"middle_fragment");
			transaction.show(fragment);
			break;

		case ScheduleListState.CREATE:
			fragment = ScheduleListFragment.newInstance();
			transaction.add(R.id.left_fragment_container, fragment);
			transaction.show(fragment);
			fragment = CreateScheduleFragment.newInstance();
			transaction.add(R.id.middle_fragment_container,
					fragment,
					"middle_fragment");
			transaction.show(fragment);
			break;

		default:
			fragment = ScheduleListFragment.newInstance();
			transaction.add(R.id.left_fragment_container, fragment);
			transaction.show(fragment);
			fragment = EmptyFragment.newInstance();
			transaction.add(R.id.middle_fragment_container,
					fragment,
					"middle_fragment");
			transaction.show(fragment);
		}
		fragment = EmptyFragment.newInstance();
		transaction.add(R.id.right_fragment_container,
				fragment,
				"right_fragment");
		transaction.hide(fragment);
	}

	/**
	 * On enregistre l'état courant de l'activité.
	 */
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		outState.putBundle(Bundles.ACTIVITY_STATE, this.state);
		super.onSaveInstanceState(outState);
	}

	/**
	 * Création de la barre d'action.
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(Menu.NONE,
				ScheduleActionBar.SYNC_ALL,
				Menu.NONE,
				"Synchroniser").setIcon(R.drawable.refresh)
				.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

		// On affiche l'icône de création uniquement si on n'affiche pas
		// le formulaire de création ou d'édition d'un emploi du temps
		int currentState = this.state == null ? ScheduleListState.OTHER
				: this.state.getInt(Bundles.FRAGMENT_STATE,
						ScheduleListState.OTHER);
		if (currentState != ScheduleListState.CREATE
				&& currentState != ScheduleListState.EDIT) {
			menu.add(Menu.NONE,
					ScheduleActionBar.CREATE_SCHEDULE,
					Menu.NONE,
					"Créer").setIcon(R.drawable.create)
					.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
		}

		menu.add(Menu.NONE,
				ScheduleActionBar.PREFERENCES,
				Menu.NONE,
				"Préférences")
				.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);

		menu.add(Menu.NONE, ScheduleActionBar.HELP, Menu.NONE, "Aide")
				.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
		return true;
	}

	/**
	 * Gestion des clicks sur la barre d'action.
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case ScheduleActionBar.SYNC_ALL:
			return true;

		case ScheduleActionBar.CREATE_SCHEDULE:
			if (this.state != null) {
				this.state.putInt(Bundles.FRAGMENT_STATE,
						ScheduleListState.CREATE);

				FragmentManager fm = this.getSupportFragmentManager();
				FragmentTransaction transaction = fm.beginTransaction();
				transaction.setCustomAnimations(android.R.anim.slide_in_left,
						android.R.anim.slide_out_right);

				Fragment fragment = CreateScheduleFragment.newInstance();
				transaction.add(R.id.middle_fragment_container,
						fragment,
						"middle_fragment");
				transaction.show(fragment);

				fragment = fm.findFragmentByTag("middle_fragment");
				if (fragment != null) {
					transaction.remove(fragment);
					transaction.hide(fragment);
				}
				transaction.commit();
				this.invalidateOptionsMenu();
			} else {
				this.startActivity(new Intent(this, CreateSchedule.class));
			}
			return true;

		case ScheduleActionBar.PREFERENCES:
			return true;

		case ScheduleActionBar.HELP:
			return true;

		default:
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * Gestion du clic sur bouton "back".
	 */
	@Override
	public void onBackPressed() {
		if (this.state != null) {
			switch (this.state.getInt(Bundles.FRAGMENT_STATE)) {
			case ScheduleListState.CREATE: //$FALL-THROUGH$
			case ScheduleListState.EDIT:
				this.state.putInt(Bundles.FRAGMENT_STATE,
						ScheduleListState.OTHER);
				this.invalidateOptionsMenu();

				FragmentManager fm = this.getSupportFragmentManager();
				FragmentTransaction transaction = fm.beginTransaction();
				transaction.setCustomAnimations(android.R.anim.slide_in_left,
						android.R.anim.slide_out_right);

				Fragment fragment = EmptyFragment.newInstance();
				transaction.add(R.id.middle_fragment_container,
						fragment,
						"middle_fragment");
				transaction.show(fragment);

				fragment = fm.findFragmentByTag("middle_fragment");
				if (fragment != null) {
					transaction.remove(fragment);
					transaction.hide(fragment);
				}
				transaction.commit();
				return;

			default:
				super.onBackPressed();
			}
		} else {
			super.onBackPressed();
		}
	}

	/**
	 * Affichage des détails pour l'emploi du temps demandé.
	 */
	@Override
	public void showScheduleDetails(long scheduleId) {
		if (this.state != null) {
			FragmentManager fm = this.getSupportFragmentManager();
			FragmentTransaction transaction = fm.beginTransaction();
			transaction.setCustomAnimations(android.R.anim.slide_in_left,
					android.R.anim.slide_out_right);

			Fragment fragment = ScheduleDetailsFragment.newInstance(scheduleId);
			transaction.add(R.id.middle_fragment_container,
					fragment,
					"middle_fragment");
			transaction.show(fragment);

			fragment = fm.findFragmentByTag("middle_fragment");
			if (fragment != null) {
				transaction.remove(fragment);
				transaction.hide(fragment);
			}

			transaction.commit();

			this.state.putLong(Bundles.SCHEDULE_ID, scheduleId);
			this.state
					.putInt(Bundles.FRAGMENT_STATE, ScheduleListState.DETAILS);
			this.invalidateOptionsMenu();
		} else {
			Intent intent = new Intent(this, ScheduleDetails.class);
			intent.putExtra(Bundles.SCHEDULE_ID, scheduleId);
			this.startActivity(intent);
		}
	}

	@Override
	public void showSchedule(long scheduleId) {
		if (this.state != null) {
			FragmentManager fm = this.getSupportFragmentManager();
			FragmentTransaction transaction = fm.beginTransaction();
			transaction.setCustomAnimations(android.R.anim.slide_in_left,
					android.R.anim.slide_out_right);

			Fragment fragment = LessonListFragment.newInstance(scheduleId);
			transaction.add(R.id.middle_fragment_container,
					fragment,
					"middle_fragment");
			transaction.show(fragment);

			fragment = fm.findFragmentByTag("middle_fragment");
			if (fragment != null) {
				transaction.remove(fragment);
				transaction.hide(fragment);
			}

			transaction.commit();

			this.state.putLong(Bundles.SCHEDULE_ID, scheduleId);
			this.state.putInt(Bundles.FRAGMENT_STATE,
					ScheduleListState.LESSON_LIST);
			this.invalidateOptionsMenu();
		} else {
			// Intent intent = new Intent(this, ScheduleDetails.class);
			// intent.putExtra(Bundles.SCHEDULE_ID, scheduleId);
			// this.startActivity(intent);
		}
	}

	@Override
	public void editSchedule(long scheduleId) {

	}

	@Override
	public void refreshSchedule(long scheduleId) {

	}

	@Override
	public void deleteSchedule(long scheduleId) {

	}

	/**
	 * ActionMode utilisé pendant l'affichage du détail d'un emploi du temps.
	 * 
	 * @author Michaël Schnell
	 * @since Jun 10, 2013
	 * 
	 * @version 1.0
	 */
	static class ScheduleActionMode
			implements ActionMode.Callback {

		@Override
		public boolean onCreateActionMode(ActionMode mode, Menu menu) {
			return false;
		}

		@Override
		public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
			return false;
		}

		@Override
		public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
			return false;
		}

		@Override
		public void onDestroyActionMode(ActionMode mode) {
		}

	}

	/**
	 * Constantes pour les identifiants des boutons de barre d'action.
	 * 
	 * @author Michaël Schnell
	 * @since Jun 10, 2013
	 * 
	 * @version 1.0
	 */
	public interface ScheduleActionBar {
		final int SYNC_ALL = 0;
		final int CREATE_SCHEDULE = 1;
		final int PREFERENCES = 2;
		final int HELP = 3;
	}

	/**
	 * Constantes pour les états possibles des fragments (version tablette).
	 * 
	 * @author Michaël Schnell
	 * @since Jun 10, 2013
	 * 
	 * @version 1.0
	 */
	public interface ScheduleListState {
		final int OTHER = 0;
		final int DETAILS = 1;
		final int CREATE = 2;
		final int EDIT = 3;
		final int LESSON_LIST = 4;
		final int LESSON_CALENDAR = 5;
		final int LESSON_LIST_AND_DETAIL = 6;
		final int LESSON_CALENDAR_AND_DETAIL = 7;
	}

}